package com.qf.security.handler;

import com.qf.aop.async.AsyncTaskFactory;
import com.qf.core.enums.common.LoginStatusEnum;
import com.qf.core.response.ResponseResult;
import com.qf.core.thread.ThreadPoolManager;
import com.qf.core.utils.BeanUtils;
import com.qf.core.utils.ServletUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.*;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author: sin
 * @Date: 2025/5/5 22:12
 * @Description: 登录失败响应
 **/
@Slf4j
public class LoginFailHandler implements AuthenticationFailureHandler {

    private static final Map<Class<? extends AuthenticationException>, String> EXCEPTION_MESSAGE_MAP = new HashMap<>();

    static {
        EXCEPTION_MESSAGE_MAP.put(UsernameNotFoundException.class, "用户名或密码错误！");
        EXCEPTION_MESSAGE_MAP.put(BadCredentialsException.class, "用户名或密码错误！");
        EXCEPTION_MESSAGE_MAP.put(AuthenticationServiceException.class, "登录服务异常，请稍后重试！");
        EXCEPTION_MESSAGE_MAP.put(LockedException.class, "账户被锁定，请联系管理员！");
        EXCEPTION_MESSAGE_MAP.put(CredentialsExpiredException.class, "证书过期，请联系管理员！");
        EXCEPTION_MESSAGE_MAP.put(AccountExpiredException.class, "账户过期，请联系管理员！");
        EXCEPTION_MESSAGE_MAP.put(DisabledException.class, "账户被禁用，请联系管理员！");
    }

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) {
        String result = EXCEPTION_MESSAGE_MAP.getOrDefault(e.getClass(), "登录失败！");
        if (e instanceof UsernameNotFoundException || e instanceof BadCredentialsException || e instanceof AuthenticationServiceException) {
            result = e.getMessage();
        }
        // 获取用户名（假设表单字段名为 "username"）
        String username = request.getParameter("username");
        log.warn("登录失败，原因：{} - {} - {}", e.getClass().getSimpleName(), e.getMessage(),username);
        // 记录登录失败日志
        ThreadPoolManager.execute(BeanUtils.getBean(AsyncTaskFactory.class).loginInfoTask("未知", LoginStatusEnum.LOGIN_FAIL,result));
        ServletUtils.renderString(response, ResponseResult.fail(result));
    }
}
